It is too demo-esque for languishing in tests/.
subdir('icon-browser')
subdir('node-editor')
subdir('widget-factory')
+subdir('print-editor')
--- /dev/null
+executable('print-editor',
+ ['print-editor.c'],
+ c_args: common_cflags,
+ dependencies: libgtk_dep,
+ include_directories: confinc,
+ gui_app: true)
--- /dev/null
+#include <config.h>
+#include <math.h>
+#include <pango/pangocairo.h>
+#include <gtk/gtk.h>
+
+static GtkWidget *main_window;
+static GFile *filename = NULL;
+static GtkPageSetup *page_setup = NULL;
+static GtkPrintSettings *settings = NULL;
+static gboolean file_changed = FALSE;
+static GtkTextBuffer *buffer;
+static GtkWidget *statusbar;
+static GList *active_prints = NULL;
+
+static void
+update_title (GtkWindow *window)
+{
+ char *basename;
+ char *title;
+
+ if (filename == NULL)
+ basename = g_strdup ("Untitled");
+ else
+ basename = g_file_get_basename (filename);
+
+ title = g_strdup_printf ("Simple Editor with printing - %s", basename);
+ g_free (basename);
+
+ gtk_window_set_title (window, title);
+ g_free (title);
+}
+
+static void
+update_statusbar (void)
+{
+ gchar *msg;
+ gint row, col;
+ GtkTextIter iter;
+ const char *print_str;
+
+ gtk_statusbar_pop (GTK_STATUSBAR (statusbar), 0);
+
+ gtk_text_buffer_get_iter_at_mark (buffer,
+ &iter,
+ gtk_text_buffer_get_insert (buffer));
+
+ row = gtk_text_iter_get_line (&iter);
+ col = gtk_text_iter_get_line_offset (&iter);
+
+ print_str = "";
+ if (active_prints)
+ {
+ GtkPrintOperation *op = active_prints->data;
+ print_str = gtk_print_operation_get_status_string (op);
+ }
+
+ msg = g_strdup_printf ("%d, %d%s %s",
+ row, col,
+ file_changed?" - Modified":"",
+ print_str);
+
+ gtk_statusbar_push (GTK_STATUSBAR (statusbar), 0, msg);
+
+ g_free (msg);
+}
+
+static void
+update_ui (void)
+{
+ update_title (GTK_WINDOW (main_window));
+ update_statusbar ();
+}
+
+static char *
+get_text (void)
+{
+ GtkTextIter start, end;
+
+ gtk_text_buffer_get_start_iter (buffer, &start);
+ gtk_text_buffer_get_end_iter (buffer, &end);
+ return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
+}
+
+static void
+set_text (const char *text,
+ gsize len)
+{
+ gtk_text_buffer_set_text (buffer, text, len);
+ file_changed = FALSE;
+ update_ui ();
+}
+
+static void
+load_file (GFile *open_filename)
+{
+ GtkWidget *error_dialog;
+ char *contents;
+ GError *error;
+ gsize len;
+
+ error_dialog = NULL;
+ error = NULL;
+ g_file_load_contents (open_filename, NULL, &contents, &len, NULL, &error);
+ if (error == NULL)
+ {
+ if (g_utf8_validate (contents, len, NULL))
+ {
+ g_clear_object (&filename);
+ filename = g_object_ref (open_filename);
+ set_text (contents, len);
+ g_free (contents);
+ }
+ else
+ {
+ GFileInfo *info = g_file_query_info (open_filename, "standard::display-name", 0, NULL, &error);
+ const char *display_name = g_file_info_get_display_name (info);
+ error_dialog = gtk_message_dialog_new (GTK_WINDOW (main_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "Error loading file %s:\n%s",
+ display_name,
+ "Not valid utf8");
+ g_object_unref (info);
+ }
+ }
+ else
+ {
+ GFileInfo *info = g_file_query_info (open_filename, "standard::display-name", 0, NULL, &error);
+ const char *display_name = g_file_info_get_display_name (info);
+ error_dialog = gtk_message_dialog_new (GTK_WINDOW (main_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "Error loading file %s:\n%s",
+ display_name,
+ error->message);
+ g_object_unref (info);
+ g_error_free (error);
+ }
+
+ if (error_dialog)
+ {
+ g_signal_connect (error_dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
+ gtk_widget_show (error_dialog);
+ }
+}
+
+
+static void
+save_file (GFile *save_filename)
+{
+ char *text = get_text ();
+ GtkWidget *error_dialog;
+ GError *error;
+
+ error = NULL;
+ g_file_replace_contents (save_filename,
+ text, -1,
+ NULL, FALSE,
+ G_FILE_CREATE_NONE,
+ NULL,
+ NULL,
+ &error);
+
+ if (error != NULL)
+ {
+ if (save_filename != filename)
+ {
+ g_clear_object (&filename);
+ filename = g_object_ref (save_filename);
+ }
+ file_changed = FALSE;
+ update_ui ();
+ }
+ else
+ {
+ GFileInfo *info = g_file_query_info (save_filename, "standard::display-name", 0, NULL, NULL);
+ const char *display_name = g_file_info_get_display_name (info);
+
+ error_dialog = gtk_message_dialog_new (GTK_WINDOW (main_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "Error saving to file %s:\n%s",
+ display_name,
+ error->message);
+
+ g_signal_connect (error_dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
+ gtk_widget_show (error_dialog);
+
+ g_error_free (error);
+ g_object_unref (info);
+ }
+}
+
+
+typedef struct {
+ char *text;
+ PangoLayout *layout;
+ GList *page_breaks;
+ GtkWidget *font_button;
+ char *font;
+} PrintData;
+
+static void
+begin_print (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ PrintData *print_data)
+{
+ PangoFontDescription *desc;
+ PangoLayoutLine *layout_line;
+ double width, height;
+ double page_height;
+ GList *page_breaks;
+ int num_lines;
+ int line;
+
+ width = gtk_print_context_get_width (context);
+ height = gtk_print_context_get_height (context);
+
+ print_data->layout = gtk_print_context_create_pango_layout (context);
+
+ desc = pango_font_description_from_string (print_data->font);
+ pango_layout_set_font_description (print_data->layout, desc);
+ pango_font_description_free (desc);
+
+ pango_layout_set_width (print_data->layout, width * PANGO_SCALE);
+
+ pango_layout_set_text (print_data->layout, print_data->text, -1);
+
+ num_lines = pango_layout_get_line_count (print_data->layout);
+
+ page_breaks = NULL;
+ page_height = 0;
+
+ for (line = 0; line < num_lines; line++)
+ {
+ PangoRectangle ink_rect, logical_rect;
+ double line_height;
+
+ layout_line = pango_layout_get_line (print_data->layout, line);
+ pango_layout_line_get_extents (layout_line, &ink_rect, &logical_rect);
+
+ line_height = logical_rect.height / 1024.0;
+
+ if (page_height + line_height > height)
+ {
+ page_breaks = g_list_prepend (page_breaks, GINT_TO_POINTER (line));
+ page_height = 0;
+ }
+
+ page_height += line_height;
+ }
+
+ page_breaks = g_list_reverse (page_breaks);
+ gtk_print_operation_set_n_pages (operation, g_list_length (page_breaks) + 1);
+
+ print_data->page_breaks = page_breaks;
+}
+
+static void
+draw_page (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ int page_nr,
+ PrintData *print_data)
+{
+ cairo_t *cr;
+ GList *pagebreak;
+ int start, end, i;
+ PangoLayoutIter *iter;
+ double start_pos;
+
+ if (page_nr == 0)
+ start = 0;
+ else
+ {
+ pagebreak = g_list_nth (print_data->page_breaks, page_nr - 1);
+ start = GPOINTER_TO_INT (pagebreak->data);
+ }
+
+ pagebreak = g_list_nth (print_data->page_breaks, page_nr);
+ if (pagebreak == NULL)
+ end = pango_layout_get_line_count (print_data->layout);
+ else
+ end = GPOINTER_TO_INT (pagebreak->data);
+
+ cr = gtk_print_context_get_cairo_context (context);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ i = 0;
+ start_pos = 0;
+ iter = pango_layout_get_iter (print_data->layout);
+ do
+ {
+ PangoRectangle logical_rect;
+ PangoLayoutLine *line;
+ int baseline;
+
+ if (i >= start)
+ {
+ line = pango_layout_iter_get_line (iter);
+
+ pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
+ baseline = pango_layout_iter_get_baseline (iter);
+
+ if (i == start)
+ start_pos = logical_rect.y / 1024.0;
+
+ cairo_move_to (cr, logical_rect.x / 1024.0, baseline / 1024.0 - start_pos);
+
+ pango_cairo_show_layout_line (cr, line);
+ }
+ i++;
+ }
+ while (i < end &&
+ pango_layout_iter_next_line (iter));
+
+ pango_layout_iter_free (iter);
+}
+
+static void
+status_changed_cb (GtkPrintOperation *op,
+ gpointer user_data)
+{
+ if (gtk_print_operation_is_finished (op))
+ {
+ active_prints = g_list_remove (active_prints, op);
+ g_object_unref (op);
+ }
+ update_statusbar ();
+}
+
+static GtkWidget *
+create_custom_widget (GtkPrintOperation *operation,
+ PrintData *data)
+{
+ GtkWidget *vbox, *hbox, *font, *label;
+
+ gtk_print_operation_set_custom_tab_label (operation, "Other");
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
+ gtk_box_append (GTK_BOX (vbox), hbox);
+ gtk_widget_show (hbox);
+
+ label = gtk_label_new ("Font:");
+ gtk_box_append (GTK_BOX (hbox), label);
+ gtk_widget_show (label);
+
+ font = gtk_font_button_new_with_font (data->font);
+ gtk_box_append (GTK_BOX (hbox), font);
+ gtk_widget_show (font);
+ data->font_button = font;
+
+ return vbox;
+}
+
+static void
+custom_widget_apply (GtkPrintOperation *operation,
+ GtkWidget *widget,
+ PrintData *data)
+{
+ const char *selected_font;
+ selected_font = gtk_font_chooser_get_font (GTK_FONT_CHOOSER (data->font_button));
+
+ g_free (data->font);
+ data->font = g_strdup (selected_font);
+}
+
+static void
+print_done (GtkPrintOperation *op,
+ GtkPrintOperationResult res,
+ PrintData *print_data)
+{
+ GError *error = NULL;
+
+ if (res == GTK_PRINT_OPERATION_RESULT_ERROR)
+ {
+
+ GtkWidget *error_dialog;
+
+ gtk_print_operation_get_error (op, &error);
+
+ error_dialog = gtk_message_dialog_new (GTK_WINDOW (main_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "Error printing file:\n%s",
+ error ? error->message : "no details");
+ g_signal_connect (error_dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
+ gtk_widget_show (error_dialog);
+ }
+ else if (res == GTK_PRINT_OPERATION_RESULT_APPLY)
+ {
+ if (settings != NULL)
+ g_object_unref (settings);
+ settings = g_object_ref (gtk_print_operation_get_print_settings (op));
+ }
+
+ g_free (print_data->text);
+ g_free (print_data->font);
+ g_free (print_data);
+
+ if (!gtk_print_operation_is_finished (op))
+ {
+ g_object_ref (op);
+ active_prints = g_list_append (active_prints, op);
+ update_statusbar ();
+
+ /* This ref is unref:ed when we get the final state change */
+ g_signal_connect (op, "status_changed",
+ G_CALLBACK (status_changed_cb), NULL);
+ }
+}
+
+static void
+end_print (GtkPrintOperation *op, GtkPrintContext *context, PrintData *print_data)
+{
+ g_list_free (print_data->page_breaks);
+ print_data->page_breaks = NULL;
+ g_object_unref (print_data->layout);
+ print_data->layout = NULL;
+}
+
+static void
+print_or_preview (GSimpleAction *action, GtkPrintOperationAction print_action)
+{
+ GtkPrintOperation *print;
+ PrintData *print_data;
+
+ print_data = g_new0 (PrintData, 1);
+
+ print_data->text = get_text ();
+ print_data->font = g_strdup ("Sans 12");
+
+ print = gtk_print_operation_new ();
+
+ gtk_print_operation_set_track_print_status (print, TRUE);
+
+ if (settings != NULL)
+ gtk_print_operation_set_print_settings (print, settings);
+
+ if (page_setup != NULL)
+ gtk_print_operation_set_default_page_setup (print, page_setup);
+
+ g_signal_connect (print, "begin_print", G_CALLBACK (begin_print), print_data);
+ g_signal_connect (print, "end-print", G_CALLBACK (end_print), print_data);
+ g_signal_connect (print, "draw_page", G_CALLBACK (draw_page), print_data);
+ g_signal_connect (print, "create_custom_widget", G_CALLBACK (create_custom_widget), print_data);
+ g_signal_connect (print, "custom_widget_apply", G_CALLBACK (custom_widget_apply), print_data);
+
+ g_signal_connect (print, "done", G_CALLBACK (print_done), print_data);
+
+ gtk_print_operation_set_export_filename (print, "test.pdf");
+
+#if 0
+ gtk_print_operation_set_allow_async (print, TRUE);
+#endif
+ gtk_print_operation_run (print, print_action, GTK_WINDOW (main_window), NULL);
+
+ g_object_unref (print);
+}
+
+static void
+activate_page_setup (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ GtkPageSetup *new_page_setup;
+
+ new_page_setup = gtk_print_run_page_setup_dialog (GTK_WINDOW (main_window),
+ page_setup, settings);
+
+ if (page_setup)
+ g_object_unref (page_setup);
+
+ page_setup = new_page_setup;
+}
+
+static void
+activate_print (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ print_or_preview (action, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG);
+}
+
+static void
+activate_preview (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ print_or_preview (action, GTK_PRINT_OPERATION_ACTION_PREVIEW);
+}
+
+static void
+on_save_response (GtkWidget *dialog,
+ int response)
+{
+ if (response == GTK_RESPONSE_OK)
+ {
+ GFile *save_filename = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
+ save_file (save_filename);
+ g_object_unref (save_filename);
+ }
+
+ gtk_window_destroy (GTK_WINDOW (dialog));
+}
+
+static void
+activate_save_as (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ GtkWidget *dialog;
+
+ dialog = gtk_file_chooser_dialog_new ("Select file",
+ GTK_WINDOW (main_window),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ "_Cancel", GTK_RESPONSE_CANCEL,
+ "_Save", GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+ gtk_widget_show (dialog);
+
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (on_save_response),
+ NULL);
+}
+
+static void
+activate_save (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ if (filename == NULL)
+ activate_save_as (action, NULL, NULL);
+ else
+ save_file (filename);
+}
+
+static void
+on_open_response (GtkWidget *dialog,
+ int response)
+{
+ if (response == GTK_RESPONSE_OK)
+ {
+ GFile *open_filename = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
+ load_file (open_filename);
+ g_object_unref (open_filename);
+ }
+
+ gtk_window_destroy (GTK_WINDOW (dialog));
+}
+
+static void
+activate_open (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ GtkWidget *dialog;
+
+ dialog = gtk_file_chooser_dialog_new ("Select file",
+ GTK_WINDOW (main_window),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ "_Cancel", GTK_RESPONSE_CANCEL,
+ "_Open", GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+ gtk_widget_show (dialog);
+
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (on_open_response),
+ NULL);
+}
+
+static void
+activate_new (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ g_free (filename);
+ filename = NULL;
+ set_text ("", 0);
+}
+
+static void
+activate_about (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ const gchar *authors[] = {
+ "Alexander Larsson",
+ NULL
+ };
+ gtk_show_about_dialog (GTK_WINDOW (main_window),
+ "name", "Print Test Editor",
+ "logo-icon-name", "text-editor-symbolic",
+ "version", PACKAGE_VERSION,
+ "copyright", "© 2006-2020 Red Hat, Inc",
+ "comments", "Program to demonstrate GTK printing.",
+ "authors", authors,
+ NULL);
+}
+
+static void
+activate_quit (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ GtkApplication *app = user_data;
+ GtkWidget *win;
+ GList *list, *next;
+
+ list = gtk_application_get_windows (app);
+ while (list)
+ {
+ win = list->data;
+ next = list->next;
+
+ gtk_window_destroy (GTK_WINDOW (win));
+
+ list = next;
+ }
+}
+
+static GActionEntry app_entries[] = {
+ { "new", activate_new, NULL, NULL, NULL },
+ { "open", activate_open, NULL, NULL, NULL },
+ { "save", activate_save, NULL, NULL, NULL },
+ { "save-as", activate_save_as, NULL, NULL, NULL },
+ { "quit", activate_quit, NULL, NULL, NULL },
+ { "about", activate_about, NULL, NULL, NULL },
+ { "page-setup", activate_page_setup, NULL, NULL, NULL },
+ { "preview", activate_preview, NULL, NULL, NULL },
+ { "print", activate_print, NULL, NULL, NULL }
+};
+
+static const gchar ui_info[] =
+ "<interface>"
+ " <menu id='appmenu'>"
+ " <section>"
+ " <item>"
+ " <attribute name='label'>_About</attribute>"
+ " <attribute name='action'>app.about</attribute>"
+ " <attribute name='accel'><Primary>a</attribute>"
+ " </item>"
+ " </section>"
+ " <section>"
+ " <item>"
+ " <attribute name='label'>_Quit</attribute>"
+ " <attribute name='action'>app.quit</attribute>"
+ " <attribute name='accel'><Primary>q</attribute>"
+ " </item>"
+ " </section>"
+ " </menu>"
+ " <menu id='menubar'>"
+ " <submenu>"
+ " <attribute name='label'>_File</attribute>"
+ " <section>"
+ " <item>"
+ " <attribute name='label'>_New</attribute>"
+ " <attribute name='action'>app.new</attribute>"
+ " <attribute name='accel'><Primary>n</attribute>"
+ " </item>"
+ " <item>"
+ " <attribute name='label'>_Open</attribute>"
+ " <attribute name='action'>app.open</attribute>"
+ " </item>"
+ " <item>"
+ " <attribute name='label'>_Save</attribute>"
+ " <attribute name='action'>app.save</attribute>"
+ " <attribute name='accel'><Primary>s</attribute>"
+ " </item>"
+ " <item>"
+ " <attribute name='label'>Save _As...</attribute>"
+ " <attribute name='action'>app.save-as</attribute>"
+ " <attribute name='accel'><Primary>s</attribute>"
+ " </item>"
+ " </section>"
+ " <section>"
+ " <item>"
+ " <attribute name='label'>Page Setup</attribute>"
+ " <attribute name='action'>app.page-setup</attribute>"
+ " </item>"
+ " <item>"
+ " <attribute name='label'>Preview</attribute>"
+ " <attribute name='action'>app.preview</attribute>"
+ " </item>"
+ " <item>"
+ " <attribute name='label'>Print</attribute>"
+ " <attribute name='action'>app.print</attribute>"
+ " </item>"
+ " </section>"
+ " </submenu>"
+ " </menu>"
+ "</interface>";
+
+static void
+buffer_changed_callback (GtkTextBuffer *text_buffer)
+{
+ file_changed = TRUE;
+ update_statusbar ();
+}
+
+static void
+mark_set_callback (GtkTextBuffer *text_buffer,
+ const GtkTextIter *new_location,
+ GtkTextMark *mark,
+ gpointer data)
+{
+ update_statusbar ();
+}
+
+static gint
+command_line (GApplication *application,
+ GApplicationCommandLine *command_line)
+{
+ int argc;
+ char **argv;
+
+ argv = g_application_command_line_get_arguments (command_line, &argc);
+
+ if (argc == 2)
+ {
+ GFile *file = g_file_new_for_commandline_arg (argv[1]);
+ load_file (file);
+ g_object_unref (file);
+ }
+
+ return 0;
+}
+
+static void
+startup (GApplication *app)
+{
+ GtkBuilder *builder;
+ GMenuModel *appmenu;
+ GMenuModel *menubar;
+
+ builder = gtk_builder_new ();
+ gtk_builder_add_from_string (builder, ui_info, -1, NULL);
+
+ appmenu = (GMenuModel *)gtk_builder_get_object (builder, "appmenu");
+ menubar = (GMenuModel *)gtk_builder_get_object (builder, "menubar");
+
+ gtk_application_set_app_menu (GTK_APPLICATION (app), appmenu);
+ gtk_application_set_menubar (GTK_APPLICATION (app), menubar);
+
+ g_object_unref (builder);
+}
+
+static void
+activate (GApplication *app)
+{
+ GtkWidget *box;
+ GtkWidget *sw;
+ GtkWidget *contents;
+
+ main_window = gtk_application_window_new (GTK_APPLICATION (app));
+ gtk_window_set_icon_name (GTK_WINDOW (main_window), "text-editor");
+ gtk_window_set_default_size (GTK_WINDOW (main_window), 400, 600);
+ gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (main_window), TRUE);
+ update_title (GTK_WINDOW (main_window));
+
+ box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_window_set_child (GTK_WINDOW (main_window), box);
+
+ /* Create document */
+ sw = gtk_scrolled_window_new (NULL, NULL);
+
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (sw), TRUE);
+
+ gtk_widget_set_vexpand (sw, TRUE);
+ gtk_box_append (GTK_BOX (box), sw);
+
+ contents = gtk_text_view_new ();
+ gtk_widget_grab_focus (contents);
+
+ gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw),
+ contents);
+
+ /* Create statusbar */
+ statusbar = gtk_statusbar_new ();
+ gtk_box_append (GTK_BOX (box), statusbar);
+
+ /* Show text widget info in the statusbar */
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (contents));
+
+ g_signal_connect_object (buffer,
+ "changed",
+ G_CALLBACK (buffer_changed_callback),
+ NULL,
+ 0);
+
+ g_signal_connect_object (buffer,
+ "mark_set", /* cursor moved */
+ G_CALLBACK (mark_set_callback),
+ NULL,
+ 0);
+
+ update_ui ();
+
+ gtk_widget_show (main_window);
+}
+
+int
+main (int argc, char **argv)
+{
+ GtkApplication *app;
+ GError *error = NULL;
+
+ gtk_init ();
+
+ settings = gtk_print_settings_new_from_file ("print-settings.ini", &error);
+ if (error) {
+ g_print ("Failed to load print settings: %s\n", error->message);
+ g_clear_error (&error);
+
+ settings = gtk_print_settings_new ();
+ }
+ g_assert (settings != NULL);
+
+ page_setup = gtk_page_setup_new_from_file ("page-setup.ini", &error);
+ if (error) {
+ g_print ("Failed to load page setup: %s\n", error->message);
+ g_clear_error (&error);
+ }
+
+ app = gtk_application_new ("org.gtk.PrintEditor", 0);
+
+ g_action_map_add_action_entries (G_ACTION_MAP (app),
+ app_entries, G_N_ELEMENTS (app_entries),
+ app);
+
+ g_signal_connect (app, "startup", G_CALLBACK (startup), NULL);
+ g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
+ g_signal_connect (app, "command-line", G_CALLBACK (command_line), NULL);
+
+ g_application_run (G_APPLICATION (app), argc, argv);
+
+ if (!gtk_print_settings_to_file (settings, "print-settings.ini", &error)) {
+ g_print ("Failed to save print settings: %s\n", error->message);
+ g_clear_error (&error);
+ }
+ if (page_setup &&
+ !gtk_page_setup_to_file (page_setup, "page-setup.ini", &error)) {
+ g_print ("Failed to save page setup: %s\n", error->message);
+ g_clear_error (&error);
+ }
+
+ return 0;
+}
['scrolling-performance', ['frame-stats.c', 'variable.c']],
['blur-performance', ['../gsk/gskcairoblur.c']],
['simple'],
- ['print-editor'],
['video-timer', ['variable.c']],
['testaccel'],
['testadjustsize'],
+++ /dev/null
-#include <config.h>
-#include <math.h>
-#include <pango/pangocairo.h>
-#include <gtk/gtk.h>
-
-static GtkWidget *main_window;
-static GFile *filename = NULL;
-static GtkPageSetup *page_setup = NULL;
-static GtkPrintSettings *settings = NULL;
-static gboolean file_changed = FALSE;
-static GtkTextBuffer *buffer;
-static GtkWidget *statusbar;
-static GList *active_prints = NULL;
-
-static void
-update_title (GtkWindow *window)
-{
- char *basename;
- char *title;
-
- if (filename == NULL)
- basename = g_strdup ("Untitled");
- else
- basename = g_file_get_basename (filename);
-
- title = g_strdup_printf ("Simple Editor with printing - %s", basename);
- g_free (basename);
-
- gtk_window_set_title (window, title);
- g_free (title);
-}
-
-static void
-update_statusbar (void)
-{
- gchar *msg;
- gint row, col;
- GtkTextIter iter;
- const char *print_str;
-
- gtk_statusbar_pop (GTK_STATUSBAR (statusbar), 0);
-
- gtk_text_buffer_get_iter_at_mark (buffer,
- &iter,
- gtk_text_buffer_get_insert (buffer));
-
- row = gtk_text_iter_get_line (&iter);
- col = gtk_text_iter_get_line_offset (&iter);
-
- print_str = "";
- if (active_prints)
- {
- GtkPrintOperation *op = active_prints->data;
- print_str = gtk_print_operation_get_status_string (op);
- }
-
- msg = g_strdup_printf ("%d, %d%s %s",
- row, col,
- file_changed?" - Modified":"",
- print_str);
-
- gtk_statusbar_push (GTK_STATUSBAR (statusbar), 0, msg);
-
- g_free (msg);
-}
-
-static void
-update_ui (void)
-{
- update_title (GTK_WINDOW (main_window));
- update_statusbar ();
-}
-
-static char *
-get_text (void)
-{
- GtkTextIter start, end;
-
- gtk_text_buffer_get_start_iter (buffer, &start);
- gtk_text_buffer_get_end_iter (buffer, &end);
- return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
-}
-
-static void
-set_text (const char *text,
- gsize len)
-{
- gtk_text_buffer_set_text (buffer, text, len);
- file_changed = FALSE;
- update_ui ();
-}
-
-static void
-load_file (GFile *open_filename)
-{
- GtkWidget *error_dialog;
- char *contents;
- GError *error;
- gsize len;
-
- error_dialog = NULL;
- error = NULL;
- g_file_load_contents (open_filename, NULL, &contents, &len, NULL, &error);
- if (error == NULL)
- {
- if (g_utf8_validate (contents, len, NULL))
- {
- g_clear_object (&filename);
- filename = g_object_ref (open_filename);
- set_text (contents, len);
- g_free (contents);
- }
- else
- {
- GFileInfo *info = g_file_query_info (open_filename, "standard::display-name", 0, NULL, &error);
- const char *display_name = g_file_info_get_display_name (info);
- error_dialog = gtk_message_dialog_new (GTK_WINDOW (main_window),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "Error loading file %s:\n%s",
- display_name,
- "Not valid utf8");
- g_object_unref (info);
- }
- }
- else
- {
- GFileInfo *info = g_file_query_info (open_filename, "standard::display-name", 0, NULL, &error);
- const char *display_name = g_file_info_get_display_name (info);
- error_dialog = gtk_message_dialog_new (GTK_WINDOW (main_window),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "Error loading file %s:\n%s",
- display_name,
- error->message);
- g_object_unref (info);
- g_error_free (error);
- }
-
- if (error_dialog)
- {
- g_signal_connect (error_dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
- gtk_widget_show (error_dialog);
- }
-}
-
-
-static void
-save_file (GFile *save_filename)
-{
- char *text = get_text ();
- GtkWidget *error_dialog;
- GError *error;
-
- error = NULL;
- g_file_replace_contents (save_filename,
- text, -1,
- NULL, FALSE,
- G_FILE_CREATE_NONE,
- NULL,
- NULL,
- &error);
-
- if (error != NULL)
- {
- if (save_filename != filename)
- {
- g_clear_object (&filename);
- filename = g_object_ref (save_filename);
- }
- file_changed = FALSE;
- update_ui ();
- }
- else
- {
- GFileInfo *info = g_file_query_info (save_filename, "standard::display-name", 0, NULL, NULL);
- const char *display_name = g_file_info_get_display_name (info);
-
- error_dialog = gtk_message_dialog_new (GTK_WINDOW (main_window),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "Error saving to file %s:\n%s",
- display_name,
- error->message);
-
- g_signal_connect (error_dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
- gtk_widget_show (error_dialog);
-
- g_error_free (error);
- g_object_unref (info);
- }
-}
-
-
-typedef struct {
- char *text;
- PangoLayout *layout;
- GList *page_breaks;
- GtkWidget *font_button;
- char *font;
-} PrintData;
-
-static void
-begin_print (GtkPrintOperation *operation,
- GtkPrintContext *context,
- PrintData *print_data)
-{
- PangoFontDescription *desc;
- PangoLayoutLine *layout_line;
- double width, height;
- double page_height;
- GList *page_breaks;
- int num_lines;
- int line;
-
- width = gtk_print_context_get_width (context);
- height = gtk_print_context_get_height (context);
-
- print_data->layout = gtk_print_context_create_pango_layout (context);
-
- desc = pango_font_description_from_string (print_data->font);
- pango_layout_set_font_description (print_data->layout, desc);
- pango_font_description_free (desc);
-
- pango_layout_set_width (print_data->layout, width * PANGO_SCALE);
-
- pango_layout_set_text (print_data->layout, print_data->text, -1);
-
- num_lines = pango_layout_get_line_count (print_data->layout);
-
- page_breaks = NULL;
- page_height = 0;
-
- for (line = 0; line < num_lines; line++)
- {
- PangoRectangle ink_rect, logical_rect;
- double line_height;
-
- layout_line = pango_layout_get_line (print_data->layout, line);
- pango_layout_line_get_extents (layout_line, &ink_rect, &logical_rect);
-
- line_height = logical_rect.height / 1024.0;
-
- if (page_height + line_height > height)
- {
- page_breaks = g_list_prepend (page_breaks, GINT_TO_POINTER (line));
- page_height = 0;
- }
-
- page_height += line_height;
- }
-
- page_breaks = g_list_reverse (page_breaks);
- gtk_print_operation_set_n_pages (operation, g_list_length (page_breaks) + 1);
-
- print_data->page_breaks = page_breaks;
-}
-
-static void
-draw_page (GtkPrintOperation *operation,
- GtkPrintContext *context,
- int page_nr,
- PrintData *print_data)
-{
- cairo_t *cr;
- GList *pagebreak;
- int start, end, i;
- PangoLayoutIter *iter;
- double start_pos;
-
- if (page_nr == 0)
- start = 0;
- else
- {
- pagebreak = g_list_nth (print_data->page_breaks, page_nr - 1);
- start = GPOINTER_TO_INT (pagebreak->data);
- }
-
- pagebreak = g_list_nth (print_data->page_breaks, page_nr);
- if (pagebreak == NULL)
- end = pango_layout_get_line_count (print_data->layout);
- else
- end = GPOINTER_TO_INT (pagebreak->data);
-
- cr = gtk_print_context_get_cairo_context (context);
-
- cairo_set_source_rgb (cr, 0, 0, 0);
-
- i = 0;
- start_pos = 0;
- iter = pango_layout_get_iter (print_data->layout);
- do
- {
- PangoRectangle logical_rect;
- PangoLayoutLine *line;
- int baseline;
-
- if (i >= start)
- {
- line = pango_layout_iter_get_line (iter);
-
- pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
- baseline = pango_layout_iter_get_baseline (iter);
-
- if (i == start)
- start_pos = logical_rect.y / 1024.0;
-
- cairo_move_to (cr, logical_rect.x / 1024.0, baseline / 1024.0 - start_pos);
-
- pango_cairo_show_layout_line (cr, line);
- }
- i++;
- }
- while (i < end &&
- pango_layout_iter_next_line (iter));
-
- pango_layout_iter_free (iter);
-}
-
-static void
-status_changed_cb (GtkPrintOperation *op,
- gpointer user_data)
-{
- if (gtk_print_operation_is_finished (op))
- {
- active_prints = g_list_remove (active_prints, op);
- g_object_unref (op);
- }
- update_statusbar ();
-}
-
-static GtkWidget *
-create_custom_widget (GtkPrintOperation *operation,
- PrintData *data)
-{
- GtkWidget *vbox, *hbox, *font, *label;
-
- gtk_print_operation_set_custom_tab_label (operation, "Other");
- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
- gtk_box_append (GTK_BOX (vbox), hbox);
- gtk_widget_show (hbox);
-
- label = gtk_label_new ("Font:");
- gtk_box_append (GTK_BOX (hbox), label);
- gtk_widget_show (label);
-
- font = gtk_font_button_new_with_font (data->font);
- gtk_box_append (GTK_BOX (hbox), font);
- gtk_widget_show (font);
- data->font_button = font;
-
- return vbox;
-}
-
-static void
-custom_widget_apply (GtkPrintOperation *operation,
- GtkWidget *widget,
- PrintData *data)
-{
- const char *selected_font;
- selected_font = gtk_font_chooser_get_font (GTK_FONT_CHOOSER (data->font_button));
-
- g_free (data->font);
- data->font = g_strdup (selected_font);
-}
-
-static void
-print_done (GtkPrintOperation *op,
- GtkPrintOperationResult res,
- PrintData *print_data)
-{
- GError *error = NULL;
-
- if (res == GTK_PRINT_OPERATION_RESULT_ERROR)
- {
-
- GtkWidget *error_dialog;
-
- gtk_print_operation_get_error (op, &error);
-
- error_dialog = gtk_message_dialog_new (GTK_WINDOW (main_window),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "Error printing file:\n%s",
- error ? error->message : "no details");
- g_signal_connect (error_dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
- gtk_widget_show (error_dialog);
- }
- else if (res == GTK_PRINT_OPERATION_RESULT_APPLY)
- {
- if (settings != NULL)
- g_object_unref (settings);
- settings = g_object_ref (gtk_print_operation_get_print_settings (op));
- }
-
- g_free (print_data->text);
- g_free (print_data->font);
- g_free (print_data);
-
- if (!gtk_print_operation_is_finished (op))
- {
- g_object_ref (op);
- active_prints = g_list_append (active_prints, op);
- update_statusbar ();
-
- /* This ref is unref:ed when we get the final state change */
- g_signal_connect (op, "status_changed",
- G_CALLBACK (status_changed_cb), NULL);
- }
-}
-
-static void
-end_print (GtkPrintOperation *op, GtkPrintContext *context, PrintData *print_data)
-{
- g_list_free (print_data->page_breaks);
- print_data->page_breaks = NULL;
- g_object_unref (print_data->layout);
- print_data->layout = NULL;
-}
-
-static void
-print_or_preview (GSimpleAction *action, GtkPrintOperationAction print_action)
-{
- GtkPrintOperation *print;
- PrintData *print_data;
-
- print_data = g_new0 (PrintData, 1);
-
- print_data->text = get_text ();
- print_data->font = g_strdup ("Sans 12");
-
- print = gtk_print_operation_new ();
-
- gtk_print_operation_set_track_print_status (print, TRUE);
-
- if (settings != NULL)
- gtk_print_operation_set_print_settings (print, settings);
-
- if (page_setup != NULL)
- gtk_print_operation_set_default_page_setup (print, page_setup);
-
- g_signal_connect (print, "begin_print", G_CALLBACK (begin_print), print_data);
- g_signal_connect (print, "end-print", G_CALLBACK (end_print), print_data);
- g_signal_connect (print, "draw_page", G_CALLBACK (draw_page), print_data);
- g_signal_connect (print, "create_custom_widget", G_CALLBACK (create_custom_widget), print_data);
- g_signal_connect (print, "custom_widget_apply", G_CALLBACK (custom_widget_apply), print_data);
-
- g_signal_connect (print, "done", G_CALLBACK (print_done), print_data);
-
- gtk_print_operation_set_export_filename (print, "test.pdf");
-
-#if 0
- gtk_print_operation_set_allow_async (print, TRUE);
-#endif
- gtk_print_operation_run (print, print_action, GTK_WINDOW (main_window), NULL);
-
- g_object_unref (print);
-}
-
-static void
-activate_page_setup (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- GtkPageSetup *new_page_setup;
-
- new_page_setup = gtk_print_run_page_setup_dialog (GTK_WINDOW (main_window),
- page_setup, settings);
-
- if (page_setup)
- g_object_unref (page_setup);
-
- page_setup = new_page_setup;
-}
-
-static void
-activate_print (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- print_or_preview (action, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG);
-}
-
-static void
-activate_preview (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- print_or_preview (action, GTK_PRINT_OPERATION_ACTION_PREVIEW);
-}
-
-static void
-on_save_response (GtkWidget *dialog,
- int response)
-{
- if (response == GTK_RESPONSE_OK)
- {
- GFile *save_filename = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
- save_file (save_filename);
- g_object_unref (save_filename);
- }
-
- gtk_window_destroy (GTK_WINDOW (dialog));
-}
-
-static void
-activate_save_as (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- GtkWidget *dialog;
-
- dialog = gtk_file_chooser_dialog_new ("Select file",
- GTK_WINDOW (main_window),
- GTK_FILE_CHOOSER_ACTION_SAVE,
- "_Cancel", GTK_RESPONSE_CANCEL,
- "_Save", GTK_RESPONSE_OK,
- NULL);
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
- gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
- gtk_widget_show (dialog);
-
- g_signal_connect (dialog, "response",
- G_CALLBACK (on_save_response),
- NULL);
-}
-
-static void
-activate_save (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- if (filename == NULL)
- activate_save_as (action, NULL, NULL);
- else
- save_file (filename);
-}
-
-static void
-on_open_response (GtkWidget *dialog,
- int response)
-{
- if (response == GTK_RESPONSE_OK)
- {
- GFile *open_filename = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
- load_file (open_filename);
- g_object_unref (open_filename);
- }
-
- gtk_window_destroy (GTK_WINDOW (dialog));
-}
-
-static void
-activate_open (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- GtkWidget *dialog;
-
- dialog = gtk_file_chooser_dialog_new ("Select file",
- GTK_WINDOW (main_window),
- GTK_FILE_CHOOSER_ACTION_OPEN,
- "_Cancel", GTK_RESPONSE_CANCEL,
- "_Open", GTK_RESPONSE_OK,
- NULL);
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
- gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
- gtk_widget_show (dialog);
-
- g_signal_connect (dialog, "response",
- G_CALLBACK (on_open_response),
- NULL);
-}
-
-static void
-activate_new (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- g_free (filename);
- filename = NULL;
- set_text ("", 0);
-}
-
-static void
-activate_about (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- const gchar *authors[] = {
- "Alexander Larsson",
- NULL
- };
- gtk_show_about_dialog (GTK_WINDOW (main_window),
- "name", "Print Test Editor",
- "logo-icon-name", "text-editor-symbolic",
- "version", PACKAGE_VERSION,
- "copyright", "© 2006-2020 Red Hat, Inc",
- "comments", "Program to demonstrate GTK printing.",
- "authors", authors,
- NULL);
-}
-
-static void
-activate_quit (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- GtkApplication *app = user_data;
- GtkWidget *win;
- GList *list, *next;
-
- list = gtk_application_get_windows (app);
- while (list)
- {
- win = list->data;
- next = list->next;
-
- gtk_window_destroy (GTK_WINDOW (win));
-
- list = next;
- }
-}
-
-static GActionEntry app_entries[] = {
- { "new", activate_new, NULL, NULL, NULL },
- { "open", activate_open, NULL, NULL, NULL },
- { "save", activate_save, NULL, NULL, NULL },
- { "save-as", activate_save_as, NULL, NULL, NULL },
- { "quit", activate_quit, NULL, NULL, NULL },
- { "about", activate_about, NULL, NULL, NULL },
- { "page-setup", activate_page_setup, NULL, NULL, NULL },
- { "preview", activate_preview, NULL, NULL, NULL },
- { "print", activate_print, NULL, NULL, NULL }
-};
-
-static const gchar ui_info[] =
- "<interface>"
- " <menu id='appmenu'>"
- " <section>"
- " <item>"
- " <attribute name='label'>_About</attribute>"
- " <attribute name='action'>app.about</attribute>"
- " <attribute name='accel'><Primary>a</attribute>"
- " </item>"
- " </section>"
- " <section>"
- " <item>"
- " <attribute name='label'>_Quit</attribute>"
- " <attribute name='action'>app.quit</attribute>"
- " <attribute name='accel'><Primary>q</attribute>"
- " </item>"
- " </section>"
- " </menu>"
- " <menu id='menubar'>"
- " <submenu>"
- " <attribute name='label'>_File</attribute>"
- " <section>"
- " <item>"
- " <attribute name='label'>_New</attribute>"
- " <attribute name='action'>app.new</attribute>"
- " <attribute name='accel'><Primary>n</attribute>"
- " </item>"
- " <item>"
- " <attribute name='label'>_Open</attribute>"
- " <attribute name='action'>app.open</attribute>"
- " </item>"
- " <item>"
- " <attribute name='label'>_Save</attribute>"
- " <attribute name='action'>app.save</attribute>"
- " <attribute name='accel'><Primary>s</attribute>"
- " </item>"
- " <item>"
- " <attribute name='label'>Save _As...</attribute>"
- " <attribute name='action'>app.save-as</attribute>"
- " <attribute name='accel'><Primary>s</attribute>"
- " </item>"
- " </section>"
- " <section>"
- " <item>"
- " <attribute name='label'>Page Setup</attribute>"
- " <attribute name='action'>app.page-setup</attribute>"
- " </item>"
- " <item>"
- " <attribute name='label'>Preview</attribute>"
- " <attribute name='action'>app.preview</attribute>"
- " </item>"
- " <item>"
- " <attribute name='label'>Print</attribute>"
- " <attribute name='action'>app.print</attribute>"
- " </item>"
- " </section>"
- " </submenu>"
- " </menu>"
- "</interface>";
-
-static void
-buffer_changed_callback (GtkTextBuffer *text_buffer)
-{
- file_changed = TRUE;
- update_statusbar ();
-}
-
-static void
-mark_set_callback (GtkTextBuffer *text_buffer,
- const GtkTextIter *new_location,
- GtkTextMark *mark,
- gpointer data)
-{
- update_statusbar ();
-}
-
-static gint
-command_line (GApplication *application,
- GApplicationCommandLine *command_line)
-{
- int argc;
- char **argv;
-
- argv = g_application_command_line_get_arguments (command_line, &argc);
-
- if (argc == 2)
- {
- GFile *file = g_file_new_for_commandline_arg (argv[1]);
- load_file (file);
- g_object_unref (file);
- }
-
- return 0;
-}
-
-static void
-startup (GApplication *app)
-{
- GtkBuilder *builder;
- GMenuModel *appmenu;
- GMenuModel *menubar;
-
- builder = gtk_builder_new ();
- gtk_builder_add_from_string (builder, ui_info, -1, NULL);
-
- appmenu = (GMenuModel *)gtk_builder_get_object (builder, "appmenu");
- menubar = (GMenuModel *)gtk_builder_get_object (builder, "menubar");
-
- gtk_application_set_app_menu (GTK_APPLICATION (app), appmenu);
- gtk_application_set_menubar (GTK_APPLICATION (app), menubar);
-
- g_object_unref (builder);
-}
-
-static void
-activate (GApplication *app)
-{
- GtkWidget *box;
- GtkWidget *sw;
- GtkWidget *contents;
-
- main_window = gtk_application_window_new (GTK_APPLICATION (app));
- gtk_window_set_icon_name (GTK_WINDOW (main_window), "text-editor");
- gtk_window_set_default_size (GTK_WINDOW (main_window), 400, 600);
- gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (main_window), TRUE);
- update_title (GTK_WINDOW (main_window));
-
- box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- gtk_window_set_child (GTK_WINDOW (main_window), box);
-
- /* Create document */
- sw = gtk_scrolled_window_new (NULL, NULL);
-
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
-
- gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (sw), TRUE);
-
- gtk_widget_set_vexpand (sw, TRUE);
- gtk_box_append (GTK_BOX (box), sw);
-
- contents = gtk_text_view_new ();
- gtk_widget_grab_focus (contents);
-
- gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw),
- contents);
-
- /* Create statusbar */
- statusbar = gtk_statusbar_new ();
- gtk_box_append (GTK_BOX (box), statusbar);
-
- /* Show text widget info in the statusbar */
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (contents));
-
- g_signal_connect_object (buffer,
- "changed",
- G_CALLBACK (buffer_changed_callback),
- NULL,
- 0);
-
- g_signal_connect_object (buffer,
- "mark_set", /* cursor moved */
- G_CALLBACK (mark_set_callback),
- NULL,
- 0);
-
- update_ui ();
-
- gtk_widget_show (main_window);
-}
-
-int
-main (int argc, char **argv)
-{
- GtkApplication *app;
- GError *error = NULL;
-
- gtk_init ();
-
- settings = gtk_print_settings_new_from_file ("print-settings.ini", &error);
- if (error) {
- g_print ("Failed to load print settings: %s\n", error->message);
- g_clear_error (&error);
-
- settings = gtk_print_settings_new ();
- }
- g_assert (settings != NULL);
-
- page_setup = gtk_page_setup_new_from_file ("page-setup.ini", &error);
- if (error) {
- g_print ("Failed to load page setup: %s\n", error->message);
- g_clear_error (&error);
- }
-
- app = gtk_application_new ("org.gtk.PrintEditor", 0);
-
- g_action_map_add_action_entries (G_ACTION_MAP (app),
- app_entries, G_N_ELEMENTS (app_entries),
- app);
-
- g_signal_connect (app, "startup", G_CALLBACK (startup), NULL);
- g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
- g_signal_connect (app, "command-line", G_CALLBACK (command_line), NULL);
-
- g_application_run (G_APPLICATION (app), argc, argv);
-
- if (!gtk_print_settings_to_file (settings, "print-settings.ini", &error)) {
- g_print ("Failed to save print settings: %s\n", error->message);
- g_clear_error (&error);
- }
- if (page_setup &&
- !gtk_page_setup_to_file (page_setup, "page-setup.ini", &error)) {
- g_print ("Failed to save page setup: %s\n", error->message);
- g_clear_error (&error);
- }
-
- return 0;
-}